#include "shape.h"

Shape::Shape(QGraphicsItem *parent) :
    QGraphicsItem(parent)
{
    init();
}

Shape::Shape(LayerType layerType)
{
    init();
    type = layerType;
    this->setZValue(layerType);
}

void Shape::init()
{
    this->setFlag(QGraphicsItem::ItemIsMovable);
    this->setAcceptHoverEvents(true);
    this->setFlag(QGraphicsItem::ItemIsSelectable);
    width = height = 1;
    grid = 5;
    scale = 1;
}

QRectF Shape::boundingRect() const
{
    return QRectF(0,0,width,height);
}

void Shape::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QBrush brush;
    QPen pen;
    QTransform tr;
    tr.scale(scale,scale);
    brush.setTransform(tr);
    if(type == METAL1)
    {
        brush.setColor(QColor(0,0,0XFF));
        pen.setColor(QColor(0,0,0XFF));
        brush.setStyle(Qt::BDiagPattern);
    }
    else if(type == METAL2)
    {
        brush.setColor(Qt::yellow);
        pen.setColor(Qt::yellow);
        brush.setStyle(Qt::BDiagPattern);
    }
    else if(type == DIFF)
    {
        brush.setColor(QColor(0,0XCC,0x66));
        pen.setColor(QColor(0,0XCC,0x66));
        brush.setStyle(Qt::SolidPattern);
    }
    else if(type == P1)
    {
        brush.setColor(QColor(0XFF,0,0));
        pen.setColor(QColor(0XFF,0,0));
        brush.setStyle(Qt::SolidPattern);
    }
    else if(type == NTUB)
    {
        brush.setColor(Qt::transparent);
        pen.setColor(Qt::white);
        brush.setStyle(Qt::SolidPattern);
    }
    else if(type == PPLUS)
    {
        brush.setColor(QColor(0XFF,0X80,0));
        pen.setColor(QColor(0XFF,0X80,0));
        brush.setStyle(Qt::Dense7Pattern);
    }
    else if(type == NPLUS)
    {
        brush.setColor(QColor(0,0XCC,0x66));
        pen.setColor(QColor(0,0XCC,0x66));
        brush.setStyle(Qt::Dense7Pattern);
    }
    else if(type == CONT)
    {
        brush.setColor(QColor(0X80,0X26,0X26));
        pen.setColor(QColor(0X80,0X26,0X26));
        brush.setStyle(Qt::SolidPattern);
    }

    if(this->isSelected())
        pen.setStyle(Qt::DashLine);

    QFont font = painter->font();
    font.setPointSizeF(font.pointSizeF()*scale*1.5);
    painter->setFont(font);
    painter->setBrush(brush);
    painter->setPen(pen);
    painter->drawRect(boundingRect());

    if(this->isSelected())
        painter->drawText(0,-5*scale, QString::number(width) + " x " + QString::number(height));
        //painter->drawText(boundingRect(),Qt::AlignCenter,QString::number(width) + " x " + QString::number(height));

    this->scene()->update();
}

void Shape::resetZValue()
{
    this->setZValue(type);
}

void Shape::setMyScale(qreal scale)
{
    this->scale *= scale;
}

void Shape::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QPointF p = event->pos();
    resize = true;

    //bottom-right
    if(this->width-p.x() < 5 && this->height - p.y() < 5)
    {
        setCursor(Qt::SizeFDiagCursor);
        this->position = BOTTOM_RIGTH;
    }
    //top-left
    else if(p.x() < 5 && p.y() < 5)
    {
        setCursor(Qt::SizeFDiagCursor);
        this->position = TOP_LEFT;
    }
    //top-right
    else if(this->width - p.x() < 5 && p.y() < 5)
    {
        setCursor(Qt::SizeBDiagCursor);
        this->position = TOP_RIGHT;
    }
    //bottom-left
    else if(this->height -p.y() < 5 && p.x() < 5)
    {
        setCursor(Qt::SizeBDiagCursor);
        this->position = BOTTOM_LEFT;
    }
    else
    {
        resize = false;
        unsetCursor();
    }
    QGraphicsItem::hoverMoveEvent(event);
}

void Shape::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    clicked = true;
    adjustPositionToTheGrid();
    QGraphicsItem::mousePressEvent(event);
}

void Shape::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    clicked = false;
    adjustPositionToTheGrid();
    QGraphicsItem::mouseReleaseEvent(event);
}

void Shape::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    int newX = this->boundingRect().left();
    int newY = this->boundingRect().top();
    int newW = this->width;
    int newH = this->height;

    if(clicked && resize)
    {
        if((int)(event->pos().x()) % grid == 0)
        {
            if(position == TOP_LEFT || position == BOTTOM_LEFT)
            {
                newX = event->pos().x();
                newW = this->boundingRect().right() - newX;

                if(newW < grid)
                {
                    newW = grid;
                    newX = width - grid;
                }
            }
            else
                newW = event->pos().x() - newX;
        }
        if((int)(event->pos().y()) % grid == 0)
        {
            if(position == TOP_LEFT || position == TOP_RIGHT)
            {
                newY = event->pos().y();
                newH = this->boundingRect().bottom() - newY;

                if(newH < grid)
                {
                    newH = grid;
                    newY = height - grid;
                }
            }
            else
                newH = event->pos().y() - newY;
        }

        QPointF newPos = mapToScene(newX, newY);

        if(newW >= grid)
            this->setX(newPos.x());
        if(newH >= grid)
            this->setY(newPos.y());

        width = newW >= grid ? newW : grid;
        height = newH >= grid ? newH : grid;
    }
    else if(clicked)
    {
        QGraphicsItem::mouseMoveEvent(event);
    }

    this->scene()->update();
}

void Shape::adjustPositionToTheGrid()
{
    int newX = this->pos().x();
    int rest = newX % grid;
    newX += rest <= 2 ? -rest : rest;

    int newY = this->pos().y();
    rest = newY % grid;
    newY += rest <= 2 ? -rest : rest;

    this->setPos(newX, newY);
}



